from app.core.crud import CRUDBase
from typing import Optional,List,Dict
from datetime import datetime

from app.services.system.copywriting_service import CopywritingService
from app.core.config import settings
from app.utils.app_log import logger

from app.models.system.aichat import ChatSession, ChatHistory
from app.schemas.system.aichat import (
    ChatRequest, ChatResponse,
    ChatSessionResponse,ChatSessionCreate,ChatMessageUpdate,
    ChatMessageResponse,ChatMessageCreate,ChatSessionUpdate)


class ChatSessionService(CRUDBase[ChatSession,ChatSessionCreate,ChatMessageUpdate]):
    def __init__(self):
        super().__init__(model=ChatSession)

    async def create_session(self, user_id: int, model: str = "qwen3:8b") -> ChatSession:
        """创建一个新的对话会话"""
        return await self.model.create(user_id=user_id, model=model)

    async def get_sessions_by_user(self, user_id: int, limit: int = 20, offset: int = 0) -> list[ChatSession]:
        """获取用户的所有对话会话（按时间倒序）"""
        return await self.model.filter(
            user_id=user_id,
            is_deleted=False
        ).order_by("-created_at").limit(limit).offset(offset)

    async def get_session_by_id(self, session_id: int, user_id: int) -> Optional[ChatSession]:
        """根据 session_id 和 user_id 获取会话（防越权）"""
        return await self.model.get(id=session_id, user_id=user_id, is_deleted=False)


class ChatHistoryService(CRUDBase[ChatHistory,ChatMessageCreate,ChatSessionUpdate]):
    def __init__(self):
        super().__init__(model=ChatHistory)

    async def add_message(self, session_id: int, role: str, content: str) -> ChatHistory:
        """添加一条消息到指定会话"""
        return await self.model.create(session_id=session_id, role=role, content=content)

    async def get_messages_by_session(self, session_id: int, limit: int = 50) -> list[ChatHistory]:
        """获取指定会话的所有消息（按顺序）"""
        return await self.model.filter(session_id=session_id).order_by("created_at").limit(limit)



class AIchatService(ChatSessionService):  # 👈 继承 ChatSessionService，复用 CRUD 能力
    """
    AI 对话服务：继承 ChatSessionService，提供对话创建 + 消息记录 + AI 生成能力
    不再继承 CopywritingService，职责清晰分离
    """

    def __init__(self):
        super().__init__()  # 初始化父类（ChatSessionService）
        self.history_service = ChatHistoryService()  # 单独管理消息
        self.client = CopywritingService().client  # 复用 OpenAI 客户端（通过包装）

    # 新增：将 ChatSession ORM 对象转为 API 响应模型
    async def to_chat_session_response(self, session: ChatSession) -> ChatSessionResponse:
        return ChatSessionResponse(
            id=session.id,
            user_id=session.user_id,
            title=session.title,
            model=session.model,
            created_at=str(session.created_at.isoformat()),
            updated_at=str(session.updated_at.isoformat()),
            is_deleted=session.is_deleted,
        )

    # 新增：将 ChatHistory ORM 对象列表转为 API 响应模型列表
    async def to_chat_message_responses(self, messages: List[ChatHistory]) -> List[ChatMessageResponse]:
        return [
            ChatMessageResponse(
                id=msg.id,
                session_id=msg.session_id,
                role=msg.role,
                content=msg.content,
                created_at=str(msg.created_at.isoformat())
            )
            for msg in messages
        ]
    
    async def apply_chat(self, request: ChatRequest, session_id: Optional[int] = None) -> ChatResponse:
        """
        执行一次 AI 对话
        如果传入 session_id，则继续该会话；否则创建新会话
        """
        try:
            # 1. 如果未传 session_id，自动创建新会话
            if not session_id:
                session = await self.create_session(
                    user_id=request.user_id, 
                    model=request.model or "qwen3:8b"
                )
                session_id = session.id
            else:
                # 可选：验证该会话是否属于当前用户（生产环境建议加）
                pass

            chat_response = ChatResponse(
                response_text="你好呀",
                usage=None,
                timestamp=datetime.utcnow().isoformat() + "Z",
                is_complete=True
            )
            content = "你好呀"

            done = True
            if done:

                # 2. 构造 messages（包含历史）
                messages: List[Dict[str, str]] = []

                # 添加系统提示（可选）
                if request.system_prompt:
                    messages.append({"role": "system", "content": request.system_prompt})

                # 加载历史消息
                history_msgs = await self.history_service.get_messages_by_session(session_id)
                for msg in history_msgs:
                    messages.append({
                        "role": msg.role,
                        "content": msg.content
                    })

                # 添加当前用户消息
                messages.append({"role": "user", "content": request.user_message})

                # 3. 调用 OpenAI
                logger.info(f"已经调用 {settings.openai_model}  {settings.openai_base_url}")
                response = await self.client.chat.completions.create(
                    model=settings.openai_model or "gpt-3.5-turbo",
                    messages=messages,
                    max_tokens=request.max_tokens,
                    temperature=request.temperature,
                    stream=False
                )
                logger.info(f"响应{response}")

                choice = response.choices[0]
                content = choice.message.content.strip() if choice.message.content else ""

                chat_response = ChatResponse(
                    response_text=content,
                    is_complete=not choice.finish_reason == "length",
                    usage=response.usage.model_dump() if response.usage else None,
                    timestamp=datetime.utcnow().isoformat() + "Z"
                )

            # 4. 记录用户消息（已在前面加载，但需再次保存以确保完整性）
            await self.history_service.add_message(session_id, "user", request.user_message)
            await self.history_service.add_message(session_id, "assistant", content)

            logger.info(f"AI对话完成 (session={session_id})，输入字符数: {len(request.user_message)}, 输出字符数: {len(content)}")
            return chat_response

        except Exception as e:
            logger.error(f"AI对话失败: {str(e)}")
            raise RuntimeError(f"AI对话服务异常: {str(e)}")
        
aichat_service = AIchatService()